program main

    use hashing, only: get_indexes, hash
    use random_module, only: randu
    use display_module, only: display
    implicit none
    integer, allocatable :: buckets(:)
    integer :: n, idx(3), i, j, k, h, m
    real :: x

    call randu(x, 1e6, 1e8)
    n = int(x)
    m = int(n*1.0)
    idx = get_indexes(n)
    call display(n, 'n:', inline=.true.)
    call display(idx(1)*idx(2)*idx(3), 'number of elements:', inline=.true.)
    call display(idx, 'idx:')
    call display(idx(1)*idx(2)*idx(3)/real(m)*100, 'load factor (%):', inline=.true.)
    allocate (buckets(0:m - 1), source=0)

    do i = 1, idx(1)
        do j = 1, idx(2)
            do k = 1, idx(3)
                h = hash(i, j, k, m)
                buckets(h) = buckets(h) + 1
            end do
        end do
    end do

    ! count the number of buckets with 0, 1, ... elements
    j = 0
    k = 0
    h = 0
    do i = 0, m - 1
        if (buckets(i) > 1) then
            h = h + 1
        else if (buckets(i) == 0) then
            k = k + 1
        end if
    end do

    ! usage percetage
    call display(100 - k/real(m)*100, 'usage percentage:', inline=.true.)
    ! print the percetage of buckets with more than one elements
    call display(h/real(m)*100, 'percentage of buckets with more than one element:', inline=.true.)

end program main
